iT邦幫忙

2025 iThome 鐵人賽

DAY 5
0
Software Development

30天收斂後端開發心法系列 第 5

30天收斂後端開發心法 - (5) Queue 是什麼?Job 又是什麼?

  • 分享至 

  • xImage
  •  

在剛接觸 Laravel 的 Queue 系統時,很多人會把 Queue(佇列) 和 Job(工作) 混為一談。但其實這兩者是不同的概念:

Queue 是什麼?

Queue 是一個「任務佇列」,你可以將需要花時間處理的任務先丟進去排隊,由背景程式(Worker)一件件處理。這樣做可以避免前端等待過久,提升整體使用者體驗。

Job 是什麼?

Job 則是一個「任務的具體實作」 — — 也就是你定義好要做什麼事情的程式邏輯,像是:寄信、壓縮影片、匯出報表等。

這些 Job 實例可以被 dispatch(派送)到 queue 裡去等待背景執行。

為什麼要用 Queue?

在這個使用者對「等待」越來越沒耐心的時代,一個操作只要卡個三秒,可能就會讓使用者直接離開。

舉個例子:你打開 YouTube,結果轉圈圈等了三圈還沒開播,是不是很煩?
應用程式也一樣,有些操作像是發送 Email,處理第三方 API 回應等,就是「花時間」的動作。

為了讓整體流程順暢,我們會把這類操作包成 Job,丟進 queue 裡去背景處理,而不是在主流程中卡住使用者。

Laravel 的 Job 要怎麼用?

1️⃣ 建立 Job 類別:複製編輯
php artisan make:job ProcessPodcast
Laravel 會產生一個位於 App\Jobs 的 Job 類別:

namespace App\Jobs;
use App\Models\Podcast;
use App\Services\AudioProcessor;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessPodcast implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, SerializesModels;
    public function __construct(
        public Podcast $podcast,
    ) {}
    public function handle(AudioProcessor $processor): void
    {
        // 實際執行的任務邏輯,例如處理 Podcast 音檔
        $processor->process($this->podcast);
    }
}

implements ShouldQueue 是關鍵:讓 Laravel 知道這是一個「應該要排入佇列處理」的 Job,而不是馬上執行。

觸發 Job(派送到佇列)

ProcessPodcast::dispatch($podcast);
這行程式碼會將任務送進你指定的 queue 中等待背景執行。

Queue 背後會存去哪裡?

你可以在 config/queue.php 中看到 queue 的預設設定:

'default' => env('QUEUE_CONNECTION', 'sync'),
Laravel 支援多種 queue「驅動(driver)」,例如:

'connections' => [
    'sync' => [
        'driver' => 'sync', // 同步,立即執行(不經過 queue)
    ],
    'database' => [
        'driver' => 'database',
        'connection' => env('DB_QUEUE_CONNECTION'),
        'table' => 'jobs',
        'queue' => 'default',
        'retry_after' => 90,
    ],
    'redis' => [
        'driver' => 'redis',
        'connection' => 'default',
        'queue' => 'default',
        'retry_after' => 90,
        'block_for' => null,
    ],
],

若你選擇使用 database 或 redis,Job 被 dispatch 後會寫入對應資料庫或 Redis 的 queue 中,等待 Laravel Worker 去處理。

那誰來負責執行這些 queue 中的任務?

有兩個主要方法:

  1. 啟動 queue worker(推薦用於即時處理):
    php artisan queue:work
    這會啟動一個常駐的 Worker,不斷地從 queue 中取出任務來執行。

  2. 用 Laravel Scheduler 配合 CronJob 執行排程任務:
    Laravel 也支援「時間排程」任務,也就是 schedule:run 指令。這通常配合系統排程工具(如 Linux 的 cron)或 Kubernetes 的 CronJob 來執行。

  • CronJob 是什麼?
    CronJob 是一種定時任務排程工具,用來在「特定時間點」自動執行命令。

在 K8S(Kubernetes)中設定 CronJob:
假設你部署在 K8S,可能會在 CronJob 設定檔中設置:

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
這表示「每分鐘」都執行一次 Laravel 的排程指令,讓 Laravel 自動檢查有哪些 Job 要執行(例如 daily, everyFiveMinutes, everyMinute)。

Cron 表達式簡介:

* * * * * 
│ │ │ │ │
│ │ │ │ └── 星期(0-6)
│ │ │ └──── 月份(1-12)
│ │ └────── 日期(1-31)
│ └──────── 小時(0-23)
└────────── 分鐘(0-59)

總結

名稱代表意義Job要被執行的具體工作邏輯(例如寄信)Queue任務排隊等待區,放入多個 Job 排隊等候處理WorkerLaravel 背後真正處理任務的執行者CronJob系統/環境層級的定時任務排程工具


上一篇
30天收斂後端開發心法 - (4) Service Provider
下一篇
30天收斂後端開發心法 - (6) 淺談測試
系列文
30天收斂後端開發心法30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言